package com.coders.powergraph;

import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import com.maag.Powerwatch.Data.PowerWatch_Common;

public class PowerGraph extends View
{
    private float             canvasHeight;
    private float             canvasWidth;

    private float             borderLeft;
    private float             borderRight;
    private float             borderTop;
    private float             borderBottom;

    private float             graphHeight;
    private float             graphWidth;

    private float             verticalGridLineCount;

    private Paint             paint;
    private List< PowerBean > list;

    public PowerGraph( Context context, List< PowerBean > list )
    {
        super( context );
        this.list = list;
        init();
    }

    public PowerGraph( Context context )
    {
        super( context );
        init();
    }

    public PowerGraph( Context context, AttributeSet attrs )
    {
        super( context, attrs );
        init();
    }

    public PowerGraph( Context context, AttributeSet attrs, int defStyle )
    {
        super( context, attrs, defStyle );
        init();
    }

    private void init()
    {
        paint = new Paint();
        borderLeft = 50;
        borderRight = 15;
        borderTop = 15;
        borderBottom = 20;
    }

    @Override
    protected void onDraw( Canvas canvas )
    {
        list = PowerWatch_Common.myList;
        canvasHeight = this.getHeight();
        canvasWidth = this.getWidth();
        Log.d( "Graph Properties", "Height=" + canvasHeight + ", Width=" + canvasWidth );

        initProperties();
        drawCanvasBackground( canvas );
        float xGgap = 25;
        float yGap = 40;
        drawChartBackground( canvas );
        drawGridLines( canvas, xGgap, yGap );
        drawXCoordinate( canvas );
        drawYCoordinate( canvas );
        updateGraph( canvas );
    }

    @Override
    protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec )
    {
        super.onMeasure( widthMeasureSpec, heightMeasureSpec );
        this.setMeasuredDimension( widthMeasureSpec, heightMeasureSpec );
    }

    private void updateGraph( Canvas canvas )
    {
        float x1 = 0;
        float y1 = 0;
        float x2 = 0;
        float y2 = 0;

        // Log.d( "Line", "MaxX=" + getMaxX() + ", MaxY=" + getMaxY() );
        // Log.d( "Line", "ModX=" + getModX() + ", ModY=" + getModY() );

        paint.setStrokeWidth( 1 );
        float modX = getModX();
        float modY = getModY();
        
        if ( null != list )
        {
            y1 = canvasHeight - borderBottom;// constant
            float indent = 0 - modX;
            for ( PowerBean bean : list )
            {
                indent += modX;
                x1 = x2 = bean.getX() + borderLeft + indent;
                if ( x1 > ( canvasWidth - borderRight ) )
                {
                    Log.e( "LineExceeded", "(x1,y1)=(" + x1 + "," + y1 + "), (x2,y2)=(" + x2 + "," + y2 + "), Color="
                            + Integer.toString( bean.getColorCode() ) );
                }
                y2 = canvasHeight - ( bean.getY() / modY ) - borderBottom;
                paint.setColor( bean.getColorCode() );
                canvas.drawLine( x1, y1, x2, y2, paint );
            }
        }
        else
        {
            Log.e( "Error", "List empty" );
        }
    }

    private void initProperties()
    {
        /*
         * if ( 0 == canvasHeight ) { canvasHeight = getHeight(); }
         * 
         * if ( 0 == canvasWidth ) { canvasWidth = getWidth(); }
         */
        graphHeight = canvasHeight - borderBottom - borderTop;
        graphWidth = canvasWidth - borderLeft - borderRight;

        Log.i( "GraphDrawingArea", "Height=" + graphHeight + "Width=" + graphWidth );
    }

    private void drawGridLines( Canvas canvas, float xGgap, float yGap )
    {
        Log.i( "getVerticalGridLines", "" + getVerticalGridLineCount() );

        float gridStroke = 5;
        float x1 = borderLeft - gridStroke;
        float y1 = canvasHeight - borderBottom;// 90
        float x2 = canvasWidth - borderRight;

        paint.setColor( Color.GRAY );
        // Horizontal lines
        float yStep = 0;
        for ( float y = y1; y > ( borderTop ); y = y - yGap )
        {
            yStep++;
            canvas.drawLine( x1, y, x2, y, paint );
        }

        drwaYlabels( canvas, yStep, yGap );

        x1 = borderLeft;
        y1 = canvasHeight - borderBottom - graphHeight;
        float y2 = canvasHeight - borderBottom + gridStroke;

        // Vertical lines
        float xStep = 0;
        for ( float x = x1; x < ( canvasWidth - borderRight ); x += xGgap )
        {
            xStep++;
            canvas.drawLine( x, y1, x, y2, paint );
        }

        drwaXlabels( canvas, xStep, xGgap );
    }

    private void drwaXlabels( Canvas canvas, float xStep, float xGgap )
    {
        float gridStroke = 5;
        float x1 = borderLeft;
        float y1 = canvasHeight - borderBottom - graphHeight;
        float y2 = canvasHeight - borderBottom + gridStroke;

        float xValue = 0;
        float maxX = getMaxX();
        xStep = maxX / ( xStep / 2 );
        for ( float x = x1; x < ( canvasWidth - borderRight ); x += ( 2 * xGgap ) )
        {
            // canvas.drawText( Float.toString( xValue ), x, y2, paint );
            // Path verticalPath = new Path();
            // verticalPath.lineTo( x, y2+gridStroke );
            // canvas.drawTextOnPath( Float.toString( xValue ), verticalPath, x,
            // y2, paint );
            // xValue += xStep;
        }
    }

    private void drwaYlabels( Canvas canvas, float yStep, float yGap )
    {
        float gridStroke = 20;
        float x1 = borderLeft - gridStroke;
        float y1 = canvasHeight - borderBottom;// 90

        paint.setColor( Color.BLACK );
        int yValue = 0;
        float maxY = getMaxY();
        yStep = maxY / yStep;
        for ( float y = y1; y > ( borderTop ); y = y - yGap )
        {
            canvas.drawText( Integer.toString( yValue ), x1 - Integer.toString( yValue ).length(), y, paint );
            yValue += yStep;
        }
    }

    private void drawYCoordinate( Canvas canvas )
    {
        float x1 = borderLeft;
        float y1 = canvasHeight - borderBottom;
        float x2 = borderLeft;
        float y2 = canvasHeight - borderTop - graphHeight;

        paint.setColor( Color.BLACK );
        paint.setStrokeWidth( 1 );
        canvas.drawLine( x1, y1, x2, y2, paint );
    }

    private void drawXCoordinate( Canvas canvas )
    {
        float x1 = borderLeft;
        float y1 = canvasHeight - borderBottom;
        float x2 = canvasWidth - borderRight;
        float y2 = canvasHeight - borderBottom;

        paint.setColor( Color.BLACK );
        paint.setStrokeWidth( 1 );
        canvas.drawLine( x1, y1, x2, y2, paint );
    }

    private void drawCanvasBackground( Canvas canvas )
    {
        canvas.drawColor( Color.WHITE );
    }

    private void drawChartBackground( Canvas canvas )
    {
        float x1 = borderLeft;
        float y1 = canvasHeight - borderBottom - graphHeight;
        float x2 = canvasWidth - borderRight;
        float y2 = canvasHeight - borderBottom;

        paint.setColor( Color.GRAY );
        canvas.drawLine( x1, y1, x2, y1, paint );
        canvas.drawLine( x2, y1, x2, y2, paint );
        // canvas.drawRect( x1, y1, x2, y2, paint );
    }

    private float getModX()
    {
        float maxX = list.size();
        float modX = ( graphWidth - borderRight ) / maxX;
        return modX;
    }

    private float getModY()
    {
        float modY = 1;
        float maxY = getMaxY();

        if ( maxY > graphHeight )
        {
            modY = ( maxY - borderTop ) / graphHeight;
        }
        return modY;
    }

    private float getMaxY()
    {
        float maxY = 0;
        for ( PowerBean bean : list )
        {
            if ( maxY < bean.getY() )
            {
                maxY = bean.getY();
            }
        }
        Log.d( "maxY", "maxY=" + maxY );
        return maxY;
    }

    private float getMaxX()
    {
        float maxX = 0;
        for ( PowerBean bean : list )
        {
            if ( maxX < bean.getX() )
            {
                maxX = bean.getX();
            }
        }
        Log.d( "maxX", "maxX=" + maxX );
        return maxX;
    }

    public float getVerticalGridLineCount()
    {
        return verticalGridLineCount;
    }

    public void setVerticalGridLineCount( float verticalGridLineCount )
    {
        this.verticalGridLineCount = verticalGridLineCount;
    }

}